<?php
/**
 * CView class file.
 * 模板解析类.
 * @author Huan Song <iphper@yeah.net>
 * @version $Id: CView.php 1 2011-04-15 19:59:26Z huan.song $
 * @package system.views
 * @since 2.0
 */
class CView implements IView
{
	/**
	 * @var array 保存模板的值.
	 */
	protected $_tpl_vars = array();
	
	/**
     * 获取模板引擎.
     * @return Object View.
     */
    public function getEngine()
    {
    	return $this;
    }
	
    /**
     * 通过键$key从$_tpl_vars中获取值.
     * <pre>
     * $view = new CView();
     * $username = $view->username;
     * $email = $view->email;
	 * </pre>
     * @param string $key.
     * @return string|array|...
     * @see __set
     */
    public function __get($key)
    {
    	if (array_key_exists($key, $this->_tpl_vars)) 
    		return $this->_tpl_vars[$key];
    	
    	return null;
    }
	
    /**
     * 判读$_tpl_vars中键$key是否存在.
     * <pre>
     * $view = new CView();
     * $bool = isset($view->username);
     * $bool = isset($view->email);
	 * </pre>
     * @param string $key.
     * @return boolean.
     */
    public function __isset($key)
    {
    	return array_key_exists($key, $this->_tpl_vars);
    }

    /**
     * 向$_tpl_vars中设置键值对.
     * <pre>
     * $view = new CView();
     * $view->username = 'iphper';
     * $view->email = 'iphper@yeah.net';
	 * </pre>
     * @param string $key 变量名.
     * @param mixed $value 变量值.
     * @return void.
     * @see assign().
     */
    public function __set($key, $value)
    {
    	$this->assign($key, $value);
    }

    /**
     * 删除$_tpl_vars中键为$key的一组键值对.
     * <pre>
     * $view = new CView();
     * unset($view->username);
     * unset($view->email);
	 * </pre>
     * @param string $key.
     * @return void.
     */
    public function __unset($key)
    {
    	if (array_key_exists($key, $this->_tpl_vars)) 
    		unset($this->_tpl_vars[$key]);
    }

    /**
     * 向$_tpl_vars中设置键值对.
     * <pre>
     * $view = new CView();
	 * $view->assign('username', 'iphper');
	 * $view->assign('email', 'iphper@yeah.net');
	 * 
	 * $vars = array('username' => 'iphper', 'email' => 'iphper@yeah.net');
	 * $view->assign($vars);
	 * </pre>
     * @param array|string $tpl_var 变量名. 如果为数组, 则循环数组赋给$_tpl_vars.
     * @param array|string|null|.etc $value 变量值.
     * @see __set().
     */
    public function assign($tpl_var, $value = null)
    {
    	if (is_array($tpl_var))
		{
            foreach ($tpl_var as $key => $value) 
			{
                if ($key != '') 
                    $this->_tpl_vars[$key] = $value;
            }
        } 
		else 
		{
            if ($tpl_var != '')
                $this->_tpl_vars[$tpl_var] = $value;
        }
    }
	
    /**
     * 获取$_tpl_vars中所有键值对.
     * <pre>
     * $view = new CView();
	 * $vars = $view->getVars();
	 * </pre>
     * @return array $_tpl_vars中所有键值对.
     */
    public function getVars()
    {
    	return $this->_tpl_vars;
    }
	
    /**
     * 清空$_tpl_vars中所有键值对.
     * <pre>
     * $view = new CView();
	 * $view->clearVars();
	 * </pre>
     * @return void.
     */
    public function clearVars()
    {
    	$this->_tpl_vars = array();
    }
    
    /**
     * 解析模板.
     * <pre>
     * $view = new CView();
	 * $html = $view->fetch('users/login.html', false);
	 * 
	 * $view->fetch('users/login.html', true); 直接输出结果.
	 * </pre>
     * @param string $tpl 模板名.
     * @param boolean $display 是否输出模板内容到浏览器.
     * @return string 解析后模板内容.
     * @throws CViewException. 如果模板文件不存在, 抛出异常.
     * @see display
     */
    public function fetch($tpl, $display = false)
    {
    	$tpl = CViewConfig::getTemplateDir() . DS . $tpl;
    	if (file_exists($tpl))
    	{
	    	extract($this->getVars());
	    	if ($display)
	    		include_once $tpl;
	    	else
	    	{
	    		ob_start();
	    		include_once $tpl;
	    		$html = ob_get_contents();
	    		ob_end_clean();
	    		return $html;
	    	}
    	}
    	else
    		throw new CViewException('CView:fetch templateFile not exists', array('{tpl}'=>$tpl));
    }
    
    /**
     * 解析并输出模板内容到浏览器.
     * <pre>
     * $view = new CView();
	 * $view->display('users/login.html');
	 * </pre>
     * @param $tpl 模板名.
     * @return void.
     * @see fetch
     */
    public function display($tpl)
    {
    	$this->fetch($tpl, true);
    }
}
